www.gusucode.com > VC++ 编写软件自动升级服务源代码 > VC++ 编写软件自动升级服务源代码/gusucode/updater_src0.8.1.6/InstallFiles.cpp
/******************************************************************** created: 2005/03/25 created: 25:3:2005 12:51 filename: InstallFiles.cpp file path: Updater file base: InstallFiles file ext: cpp author: Geert van Horrik purpose: *********************************************************************/ //********************************************************************* // INCLUDES //********************************************************************* #include "stdafx.h" #include "Updater.h" #include "InstallFiles.h" #include "Unzipper.h" // Unzip support #include "BackUp.h" // Backup support typedef HRESULT (* DLLREGISTERSERVERPROC)(); //********************************************************************* // MESSAGE MAP //********************************************************************* BEGIN_MESSAGE_MAP(CInstallFiles, CWinThread) ON_THREAD_MESSAGE(WMU_INSTALL_START, OnInstallStart) ON_THREAD_MESSAGE(WMU_INSTALLFILES_COMPLETE, OnFileComplete) ON_THREAD_MESSAGE(WMU_INSTALLACTION_COMPLETE, OnActionComplete) ON_THREAD_MESSAGE(WMU_BACKUP_STATUS, OnBackUpStatus) ON_THREAD_MESSAGE(WMU_BACKUP_COMPLETE, OnBackUpComplete) ON_THREAD_MESSAGE(WMU_ERROR, OnError) ON_THREAD_MESSAGE(WMU_WARNING_COMPLETE, OnWarningComplete) ON_THREAD_MESSAGE(WMU_QUESTION_ANSWER, OnQuestionAnswer) ON_THREAD_MESSAGE(WMU_COPY_STATUS, OnCopyStatus) ON_THREAD_MESSAGE(WMU_COPY_COMPLETE, OnCopyComplete) ON_THREAD_MESSAGE(WMU_SETPARENT, OnSetParent) END_MESSAGE_MAP() //********************************************************************* // CONSTRUCTOR & DESTRUCTOR //********************************************************************* IMPLEMENT_DYNCREATE(CInstallFiles, CWinThread) //===================================================================== CInstallFiles::CInstallFiles() { } //===================================================================== CInstallFiles::~CInstallFiles() { } //********************************************************************* // PUBLIC FUNCTIONS //********************************************************************* BOOL CInstallFiles::InitInstance() { // Log CLog::Instance()->Log("CInstallFiles::InitInstance()"); // Init singleton classes m_pUpdateInfo = CUpdateInfo::Instance(); m_pFunctions = CFunctions::Instance(); m_pLanguage = CLanguage::Instance(); m_pPath = CPath::Instance(); // Set number of actions to zero m_InstallStatus.iTotalActions = 0; m_InstallStatus.iTotalActionsPerformed = 0; // Calculate actions for (int i = 0; i < m_pUpdateInfo->GetFileCount(); i++) { m_InstallStatus.iTotalActions += CalculateActionsOfFile(i); } // Set install type m_InstallStatus.iInstallPart = INSTALL_FILES; return TRUE; } //===================================================================== int CInstallFiles::ExitInstance() { // Log CLog::Instance()->Log("CInstallFiles::ExitInstance()"); // Is there a copy thread runnig? if (!IsBadReadPtr(m_pCopyThread, sizeof(CCopyFile *))) { // End thread m_pCopyThread->PostThreadMessage(WM_QUIT, 0, 0); // Wait until thread has really ended WaitForSingleObject(m_pCopyThread->m_hThread, INFINITE); } // Is there a backup thread runnig? if (!IsBadReadPtr(m_pBackupThread, sizeof(CBackUp *))) { // End thread m_pBackupThread->PostThreadMessage(WM_QUIT, 0, 0); // Wait until thread has really ended WaitForSingleObject(m_pBackupThread->m_hThread, INFINITE); } return CWinThread::ExitInstance(); } //===================================================================== int CInstallFiles::GetActionCount() { // Return value return m_InstallStatus.iTotalActions; } //********************************************************************* // PRIVATE FUNCTIONS //********************************************************************* void CInstallFiles::BackUpObject() { // Declare variables bool bBackup = false; CString sType; // Get object CFileData * pFileData = m_pUpdateInfo->GetFileData(m_iCurrentFile); // Prepare info m_InstallStatus.sTitle.Format(m_pLanguage->GetString(IDS_ACTION_BACKUP), pFileData->GetName()); m_InstallStatus.iFileActions = CalculateBackupActionsOfAction(m_iCurrentFile, m_iCurrentAction); SendInstallStatus(); // Create backup thread m_pBackupThread = (CBackUp *)AfxBeginThread(RUNTIME_CLASS(CBackUp), THREAD_PRIORITY_NORMAL, 0, 0, NULL); // Set parent m_pBackupThread->SetParent(this); // Check how to backup sType = pFileData->GetAction(m_iCurrentAction)->GetType(); // Unzip if (sType == ACTION_UNZIP) { // Get object CActionUnzip * pUnzip = (CActionUnzip *) pFileData->GetAction(m_iCurrentAction); // Backup m_pBackupThread->StartBackUpFolder(pUnzip->GetDestination()); } // Delete if (sType == ACTION_DELETE) { // Get object CActionDelete * pDelete = (CActionDelete *) pFileData->GetAction(m_iCurrentAction); // Backup m_pBackupThread->StartBackUpFile(pDelete->GetDeleteLocation()); } // Copy if (sType == ACTION_COPY) { // Get object CActionCopy * pCopy = (CActionCopy *) pFileData->GetAction(m_iCurrentAction); // Backup m_pBackupThread->StartBackUpFile(pCopy->GetNewLocation()); } // Register if (sType == ACTION_REGISTER) { // Get object CActionRegister * pRegister = (CActionRegister *) pFileData->GetAction(m_iCurrentAction); // Backup m_pBackupThread->StartBackUpRegister(pRegister->GetLocation()); } } //===================================================================== void CInstallFiles::InstallFile(int iFile) { // Set current file m_iCurrentFile = iFile; // Should we update the file? if (m_pUpdateInfo->GetFileData(iFile)->GetUpdateFile()) { // Prepare info m_InstallStatus.iFileActionsPerformed = 0; m_InstallStatus.iFileActions = CalculateActionsOfFile(m_iCurrentFile); // Start first action of file m_iCurrentAction = -1; PerformNextAction(); } else { // Don't update, go to next file InstallNextFile(); } } //===================================================================== void CInstallFiles::InstallNextFile() { // Update current file m_iCurrentFile++; // Are there still files left in this part? if (m_iCurrentFile < m_pUpdateInfo->GetFileCount()) { // Install next file InstallFile(m_iCurrentFile); } else { // Send message to parent that we are ready PostMessageToParent(WMU_INSTALL_COMPLETE, INSTALL_FILES, 0); } } //===================================================================== void CInstallFiles::PerformAction(int iAction) { // Declare variables CString sActionType; bool bActionRun = false; // Set current action m_iCurrentAction = iAction; // Check what action to perform sActionType = m_pUpdateInfo->GetFileData(m_iCurrentFile)->GetAction(iAction)->GetType(); // Calculate action points m_InstallStatus.iFileActionsPerformed = 0; // Copy if (sActionType == ACTION_COPY) { // Should we backup? if (m_pUpdateInfo->GetRollbackEnabled()) { // First backup BackUpObject(); } else { // Perform action immediatly PerformActionCopy(m_pUpdateInfo->GetFileData(m_iCurrentFile), m_iCurrentAction); } bActionRun = true; } // Delete if (sActionType == ACTION_DELETE) { // Should we backup? if (m_pUpdateInfo->GetRollbackEnabled()) { // First backup BackUpObject(); } else { // Perform action immediatly PerformActionDelete(m_pUpdateInfo->GetFileData(m_iCurrentFile), m_iCurrentAction); } bActionRun = true; } // Run if (sActionType == ACTION_RUN) { // No backup is needed bActionRun = true; PerformActionRun(m_pUpdateInfo->GetFileData(m_iCurrentFile), m_iCurrentAction); } // Unzip if (sActionType == ACTION_UNZIP) { // Should we backup? if (m_pUpdateInfo->GetRollbackEnabled()) { // First backup BackUpObject(); } else { // Perform action immediatly PerformActionUnzip(m_pUpdateInfo->GetFileData(m_iCurrentFile), m_iCurrentAction); } bActionRun = true; } // Set file attributes if (sActionType == ACTION_SETFILEATTR) { // No backup is needed bActionRun = true; PerformActionSetFileAttr(m_pUpdateInfo->GetFileData(m_iCurrentFile), m_iCurrentAction); } // Register file if (sActionType == ACTION_REGISTER) { // Should we backup? if (m_pUpdateInfo->GetRollbackEnabled()) { // First backup BackUpObject(); } else { // Perform action immediatly PerformActionRegister(m_pUpdateInfo->GetFileData(m_iCurrentFile), m_iCurrentAction); } bActionRun = true; } // Were we able to run any action? if (!bActionRun) { // It was probably a download or something, go to next action PostThreadMessage(WMU_INSTALLACTION_COMPLETE, 0, 0); } } //===================================================================== void CInstallFiles::PerformNextAction() { // Update current action m_iCurrentAction++; // Are there still actions left in this file? if (m_iCurrentAction < m_pUpdateInfo->GetFileData(m_iCurrentFile)->GetActionCount()) { // Start next action PerformAction(m_iCurrentAction); } else { // Install next file InstallNextFile(); } } //===================================================================== void CInstallFiles::PerformActionCopy(CFileData * pFileData, int iActionIndex) { // Get info CActionCopy * pInfo = (CActionCopy *)pFileData->GetAction(iActionIndex); // Update info m_InstallStatus.sTitle.Format(m_pLanguage->GetString(IDS_ACTION_COPY), pFileData->GetName()); m_InstallStatus.iFileActions = CalculateActionsOfAction(m_iCurrentFile, m_iCurrentAction); m_InstallStatus.iFileActionsPerformed = 0; SendInstallStatus(); // Start thread m_pCopyThread = (CCopyFile *)AfxBeginThread(RUNTIME_CLASS(CCopyFile), THREAD_PRIORITY_NORMAL, 0, 0, NULL); // Set parent m_pCopyThread->SetParent(this); // Init copy m_pCopyThread->StartFileCopy(pInfo->GetOldLocation(), pInfo->GetNewLocation(), !pInfo->GetOverwrite()); } //===================================================================== void CInstallFiles::PerformActionDelete(CFileData * pFileData, int iActionIndex) { // Get info CActionDelete * pInfo = (CActionDelete *)pFileData->GetAction(iActionIndex); CSettings * pSettings = CSettings::Instance(); // Update info m_InstallStatus.sTitle.Format(m_pLanguage->GetString(IDS_ACTION_DELETE), pFileData->GetName()); m_InstallStatus.iFileActions = CalculateActionsOfAction(m_iCurrentFile, m_iCurrentAction); m_InstallStatus.iFileActionsPerformed = 0; SendInstallStatus(); // Check if we should ask user if (pInfo->GetAskConfirmation()) { // We should ask PostMessageToParent(WMU_QUESTION, QUESTION_DELETEFILE, (WPARAM)pInfo); } else { // Delete file ContinueActionDelete(); // Finish it FinishActionDelete(); } } //===================================================================== void CInstallFiles::PerformActionRun(CFileData * pFileData, int iActionIndex) { // Get info CActionRun * pInfo = (CActionRun *)pFileData->GetAction(iActionIndex); // Declare variables CString sDirectory; // Update info m_InstallStatus.sTitle.Format(m_pLanguage->GetString(IDS_ACTION_RUN), pFileData->GetName()); m_InstallStatus.iFileActions = CalculateActionsOfAction(m_iCurrentFile, m_iCurrentAction); m_InstallStatus.iFileActionsPerformed = 0; SendInstallStatus(); // Check if the user tries to open a website if (!m_pFunctions->IsWebAddress(pInfo->GetRunLocation())) { // Check if file exists if (!PathFileExists(pInfo->GetRunLocation())) { // Send error message PostMessageToParent(WMU_ERROR, ERROR_FILENOTFOUND, 0); // Maybe we should even stop executing return; } } // Prepare shellExecutInfo sDirectory = m_pPath->ExtractFilePath(pInfo->GetRunLocation()); SHELLEXECUTEINFO ShRun = {0}; ShRun.cbSize = sizeof(SHELLEXECUTEINFO); ShRun.fMask = SEE_MASK_NOCLOSEPROCESS; ShRun.hwnd = NULL; ShRun.lpVerb = NULL; ShRun.lpFile = pInfo->GetRunLocation(); ShRun.lpParameters = pInfo->GetParameters(); ShRun.lpDirectory = sDirectory; ShRun.nShow = SW_SHOW; ShRun.hInstApp = NULL; // Execute the file with the parameters if (!ShellExecuteEx(&ShRun)) { // Send error message PostMessageToParent(WMU_ERROR, ERROR_RUNFILE, 0); // Maybe we should even stop executing return; } // Should we wait? if (pInfo->GetWaitUntilReady()) { // Wait until process is ready WaitForSingleObject(ShRun.hProcess, INFINITE); } // Update information m_InstallStatus.iFileActionsPerformed = ACTIONPOINTS_RUN; m_InstallStatus.iTotalActionsPerformed += ACTIONPOINTS_RUN; SendInstallStatus(); // We are ready! PostThreadMessage(WMU_INSTALLACTION_COMPLETE, 0, 0); } //===================================================================== void CInstallFiles::PerformActionUnzip(CFileData * pFileData, int iActionIndex) { // Get info CActionUnzip * pInfo = (CActionUnzip *)pFileData->GetAction(iActionIndex); // Declare variables CUnzipper zipUnzip; int iFileCount; // Update info m_InstallStatus.sTitle.Format(m_pLanguage->GetString(IDS_ACTION_UNZIP), pFileData->GetName()); m_InstallStatus.iFileActions = CalculateActionsOfAction(m_iCurrentFile, m_iCurrentAction); m_InstallStatus.iFileActionsPerformed = 0; SendInstallStatus(); // Open the zip file if (!zipUnzip.OpenZip(pInfo->GetLocation())) { // Send error message PostMessageToParent(WMU_ERROR, ERROR_UNZIPFILE, 0); // Maybe we should even stop executing return; } // Do we have any files? iFileCount = zipUnzip.GetFileCount(); if (iFileCount == 0) return; // Go to first file if (!zipUnzip.GotoFirstFile()) return; // Unzip all files do { if (!zipUnzip.UnzipFile(pInfo->GetDestination())) { // Send error message PostMessageToParent(WMU_ERROR, ERROR_UNZIPFILE, 0); // Close zip file zipUnzip.CloseZip(); // Maybe we should even stop executing return; } // Update information m_InstallStatus.iFileActionsPerformed++; m_InstallStatus.iTotalActionsPerformed++; SendInstallStatus(); // Should we continue unzipping? if (!m_pParent) { // Stop yourself PostThreadMessage(WM_QUIT, 0, 0); } } while (zipUnzip.GotoNextFile()); // Close zip file zipUnzip.CloseZip(); // Update information m_InstallStatus.iFileActionsPerformed = m_InstallStatus.iFileActions; m_InstallStatus.iTotalActionsPerformed++; SendInstallStatus(); // We are ready! PostThreadMessage(WMU_INSTALLACTION_COMPLETE, 0, 0); } //===================================================================== void CInstallFiles::PerformActionSetFileAttr(CFileData * pFileData, int iActionIndex) { // Get info CActionSetFileAttr * pInfo = (CActionSetFileAttr *)pFileData->GetAction(iActionIndex); // Update info m_InstallStatus.sTitle.Format(m_pLanguage->GetString(IDS_ACTION_SETFILEATTR), pFileData->GetName()); m_InstallStatus.iFileActions = CalculateActionsOfAction(m_iCurrentFile, m_iCurrentAction); m_InstallStatus.iFileActionsPerformed = 0; SendInstallStatus(); // Set file attributes SetFileAttributes(pInfo->GetLocation(), pInfo->GetAttributes()); // Update information m_InstallStatus.iFileActionsPerformed = m_InstallStatus.iFileActions; m_InstallStatus.iTotalActionsPerformed++; SendInstallStatus(); // We are ready! PostThreadMessage(WMU_INSTALLACTION_COMPLETE, 0, 0); } //===================================================================== void CInstallFiles::PerformActionRegister(CFileData * pFileData, int iActionIndex) { // Get info CActionRegister * pInfo = (CActionRegister *)pFileData->GetAction(iActionIndex); // Update info m_InstallStatus.sTitle.Format(m_pLanguage->GetString(IDS_ACTION_REGISTER), pFileData->GetName()); m_InstallStatus.iFileActions = CalculateActionsOfAction(m_iCurrentFile, m_iCurrentAction); m_InstallStatus.iFileActionsPerformed = 0; SendInstallStatus(); // Check if we should ask user if (pInfo->GetAskUser()) { // We should ask PostMessageToParent(WMU_QUESTION, QUESTION_REGISTERFILE, (WPARAM)pInfo); } else { // Register file ContinueActionRegister(); // Finish it FinishActionRegister(); } } //===================================================================== void CInstallFiles::ContinueActionDelete() { // Declare variables CActionDelete * pInfo = (CActionDelete *) m_pUpdateInfo->GetFileData(m_iCurrentFile)->GetAction(m_iCurrentAction); // Delete the file DeleteFile(pInfo->GetDeleteLocation()); } //===================================================================== void CInstallFiles::FinishActionDelete() { // Update information m_InstallStatus.iFileActionsPerformed = ACTIONPOINTS_DELETE; m_InstallStatus.iTotalActionsPerformed += ACTIONPOINTS_DELETE; SendInstallStatus(); // We are ready with the install action, continue PostThreadMessage(WMU_INSTALLACTION_COMPLETE, 0, 0); } //===================================================================== bool CInstallFiles::ContinueActionRegister() { // Declare variables bool bFailed = false; CSettings * pSettings = CSettings::Instance(); HMODULE hMod; DLLREGISTERSERVERPROC DllRegisterServerFunction; // Get info CActionRegister * pInfo = (CActionRegister *) m_pUpdateInfo->GetFileData(m_iCurrentFile)->GetAction(m_iCurrentAction); // Enable COM ::CoInitialize(NULL); // Register file hMod = LoadLibrary(pInfo->GetLocation()); // Check if we can load library if (hMod != NULL) { // Get proc address DllRegisterServerFunction = (DLLREGISTERSERVERPROC) GetProcAddress(hMod, "DllRegisterServer"); // Check if we can run the function if (DllRegisterServerFunction != NULL) { // Register if (FAILED(DllRegisterServerFunction())) { // We failed bFailed = true; } } else { // We failed bFailed = true; } } else { // We failed bFailed = true; } // Disable COM ::CoUninitialize(); // Return result return !bFailed; } //===================================================================== void CInstallFiles::FinishActionRegister() { // Update information m_InstallStatus.iFileActionsPerformed = m_InstallStatus.iFileActions; m_InstallStatus.iTotalActionsPerformed++; SendInstallStatus(); // We are ready with the install action, continue PostThreadMessage(WMU_INSTALLACTION_COMPLETE, 0, 0); } //===================================================================== void CInstallFiles::SendInstallStatus() { // Send status to parent if (m_pParent) PostMessageToParent(WMU_INSTALL_STATUS, (WPARAM)&m_InstallStatus, 0); } //===================================================================== void CInstallFiles::PostMessageToParent(UINT message, WPARAM wParam, LPARAM lParam) { // Check if parent is still valid if (!IsBadReadPtr(m_pParent, sizeof(CWinThread *))) { // Send message m_pParent->PostThreadMessage(message, wParam, lParam); } } //===================================================================== int CInstallFiles::CalculateActionsOfFile(int iFile) { // Declare variables int iActionCount = 0; // Get file info CFileData * pTempFile = m_pUpdateInfo->GetFileData(iFile); // Should we install file? if (pTempFile->GetUpdateFile()) { // Calculate for all actions for (int i = 0; i < pTempFile->GetActionCount(); i++) { iActionCount += CalculateActionsOfAction(iFile, i); if (m_pUpdateInfo->GetRollbackEnabled()) { iActionCount += CalculateBackupActionsOfAction(iFile, i); } } } // Return value return iActionCount; } //===================================================================== int CInstallFiles::CalculateActionsOfAction(int iFile, int iAction) { // Declare variables int iActionCount; // Get action info CActionBase * pTempAction = m_pUpdateInfo->GetFileData(iFile)->GetAction(iAction); // Calculate actionpoints iActionCount = CActionPoints::CalculateActionPoints(pTempAction); // Return value return iActionCount; } //===================================================================== int CInstallFiles::CalculateBackupActionsOfAction(int iFile, int iAction) { // Declare variables int iActionCount = 0; // Get action info CActionBase * pTempAction = m_pUpdateInfo->GetFileData(iFile)->GetAction(iAction); // Check if action is unzip if (pTempAction->GetType() == ACTION_UNZIP) { // Get object CActionUnzip * pTempUnzip = (CActionUnzip *)pTempAction; // Get actionpoints iActionCount += CActionPoints::CalculateActionPoints(pTempUnzip->GetDestination()); } // Check if action is copy if (pTempAction->GetType() == ACTION_COPY) { // Get object CActionCopy * pTempCopy = (CActionCopy *)pTempAction; // Get actionpoints iActionCount += CActionPoints::CalculateActionPoints(pTempCopy->GetNewLocation()); } // Check if action is delete if (pTempAction->GetType() == ACTION_DELETE) { // Run is 1 action iActionCount += ACTIONPOINTS_DELETE; } // Check if action is register if (pTempAction->GetType() == ACTION_REGISTER) { // Run is 1 action iActionCount += ACTIONPOINTS_REGISTER; } // Return value return iActionCount; } //===================================================================== void CInstallFiles::OnInstallStart(WPARAM wParam, LPARAM lParam) { // Install first file m_iCurrentFile = -1; InstallNextFile(); } //===================================================================== void CInstallFiles::OnFileComplete(WPARAM wParam, LPARAM lParam) { // Start next file InstallNextFile(); } //===================================================================== void CInstallFiles::OnActionComplete(WPARAM wParam, LPARAM lParam) { // Start next action PerformNextAction(); } //===================================================================== void CInstallFiles::OnBackUpStatus(WPARAM wParam, LPARAM lParam) { // Update data m_InstallStatus.iTotalActionsPerformed += wParam - m_InstallStatus.iFileActionsPerformed; m_InstallStatus.iFileActionsPerformed += wParam - m_InstallStatus.iFileActionsPerformed; SendInstallStatus(); } //===================================================================== void CInstallFiles::OnBackUpComplete(WPARAM wParam, LPARAM lParam) { // Declare variables CString sActionType; // Check what action to perform sActionType = m_pUpdateInfo->GetFileData(m_iCurrentFile)->GetAction(m_iCurrentAction)->GetType(); // Calculate action points m_InstallStatus.iTotalActionsPerformed += wParam - m_InstallStatus.iFileActionsPerformed; m_InstallStatus.iFileActionsPerformed = m_InstallStatus.iFileActions; // Copy if (sActionType == ACTION_COPY) { // Perform action immediatly PerformActionCopy(m_pUpdateInfo->GetFileData(m_iCurrentFile), m_iCurrentAction); } // Delete if (sActionType == ACTION_DELETE) { // Perform action PerformActionDelete(m_pUpdateInfo->GetFileData(m_iCurrentFile), m_iCurrentAction); } // Unzip if (sActionType == ACTION_UNZIP) { // Perform action PerformActionUnzip(m_pUpdateInfo->GetFileData(m_iCurrentFile), m_iCurrentAction); } // Register if (sActionType == ACTION_REGISTER) { // Perform action PerformActionRegister(m_pUpdateInfo->GetFileData(m_iCurrentFile), m_iCurrentAction); } } //===================================================================== void CInstallFiles::OnError(WPARAM wParam, LPARAM lParam) { // An error occurred! PostMessageToParent(WMU_ERROR, wParam, lParam); } //===================================================================== void CInstallFiles::OnWarningComplete(WPARAM wParam, LPARAM lParam) { // We are ready with the install action, continue PostThreadMessage(WMU_INSTALLACTION_COMPLETE, 0, 0); } //===================================================================== void CInstallFiles::OnQuestionAnswer(WPARAM wParam, LPARAM lParam) { // Declare variables int iQuestion = wParam; int iAnswer = lParam; // Check what question has an answer switch (iQuestion) { case QUESTION_DELETEFILE: // Check answer if (iAnswer == QUESTIONRESULT_YES) { // Continue deleting ContinueActionDelete(); } // Finish deleting FinishActionDelete(); break; case QUESTION_REGISTERFILE: // Check answer if (iAnswer == QUESTIONRESULT_YES) { // Continue registering file if (!ContinueActionRegister()) { // Post warning PostMessageToParent(WMU_WARNING, WARNING_REGISTER, 0); return; } } // Finish registering FinishActionRegister(); break; } } //===================================================================== void CInstallFiles::OnCopyStatus(WPARAM wParam, LPARAM lParam) { // Calculate actions performed m_InstallStatus.iTotalActionsPerformed += wParam - m_InstallStatus.iFileActionsPerformed; m_InstallStatus.iFileActionsPerformed += wParam - m_InstallStatus.iFileActionsPerformed; // Send install status SendInstallStatus(); } //===================================================================== void CInstallFiles::OnCopyComplete(WPARAM wParam, LPARAM lParam) { // Update information m_InstallStatus.iTotalActionsPerformed += m_InstallStatus.iFileActions - m_InstallStatus.iFileActionsPerformed; m_InstallStatus.iFileActionsPerformed = m_InstallStatus.iFileActions; // Send install status SendInstallStatus(); // Start next action PerformNextAction(); } //===================================================================== void CInstallFiles::OnSetParent(WPARAM wParam, LPARAM lParam) { // Set parent m_pParent = (CWinThread *)wParam; }